import axios from 'axios';
import { Dialog, Toast } from 'vant';
import { logout } from '@/utils/login';
import router from '@/router';
// 接口超时时间5秒
const TIME_OUT = 5000;
// 会话响应时间5分钟
const OPERATION_OUT = 300000;
const ERR_MSG = '服务器在忙，请退出后重试';
// 加载提示
function showLoading() {
    return Toast.loading({
        message: '加载中···',
        forbidClick: true
    });
}

function hideLoading() {
    Toast.clear();
}


//警告提示
const warn = (ec, msg) => {
    if (!ec) {
        ec = '';
        msg = '服务异常，请稍后重试'
    }
    Dialog.alert({
        title: '温馨提示',
        message: msg + '\n' + ec,
        confirmButtonText: '知道了'
    })
    return msg + '\n' + ec
}

// 报错退出
const warnWithLogin = (ec, msg) => {
    if (!ec) {
        ec = '';
        msg = '服务异常，请稍后重试';
    }
    Dialog.alert({
        title: '温馨提示',
        message: msg + '\n' + ec,
        confirmButtonText: '知道了'
    }).then(() => {
        logout()
    });
    return msg + '\n' + ec
};

/**
 * 长时间无任何操作
 */
const longTimeNoOperation = () => {
    hideLoading()
    Dialog.alert({
        title: '温馨提示',
        message: '长时间未进行操作,为保证您的账户安全,请重新登录',
        confirmButtonText: '去登录',
        theme: 'round-button',
    }).then(() => {
        // 调用退出接口
        logout()
    });
};

/**
 * 检查需要会话的API,间隔时间是否超过5分钟,否则重定向到会话超时页面
 * @param path 当前请求接口名称
 */
const checkTimeOut = (path) => {
    const nowTime = Date.now();
    const lastTime = parseFloat(sessionStorage.getItem('lastRpcTime') || 0);
    if (lastTime && nowTime - lastTime > OPERATION_OUT) {
        sessionStorage.setItem('lastRpcTime', '0');
        longTimeNoOperation();//暂时先注释不提示，需要了打开
        return;
    }
    if (process.env.NODE_ENV === 'development') {
        if (router.currentRoute.name === 'login') {
            sessionStorage.setItem('lastRpcTime', '0');
        } else {
            sessionStorage.setItem('lastRpcTime', String(nowTime));

        }
        return false;
    } else {
        // 生产环境根据接口判断
        if (path === '/loginOut') {
            sessionStorage.setItem('lastRpcTime', '0');
        } else {
            sessionStorage.setItem('lastRpcTime', String(nowTime));
        }
        return false;
    }

};
//创建axios对象
const service = axios.create({
    baseURL: process.env.VUE_APP_BASE_URL,
    timeout: TIME_OUT,
    checkToken: true,//接口请求是否带token
});

//定义请求数据类型
service.defaults.headers['Content-Type'] = 'application/json;charset=utf-8';

//请求拦截器
service.interceptors.request.use(async function (config) {
    // 获取当前调用的接口
    const url = config.url
    // 显示加载状态
    if (config.isLoad) {
        showLoading()
    }
    //超时退出
    if (checkTimeOut(url)) {
        return Promise.resolve();
    }
    const userToken = await localStorage.getItem('userToken');
    //在请求头中加token
    if (config.checkToken) {
        config.headers['token'] = userToken;
    }
    // 在发送请求之前
    return config;
},
    (error) => {
        //请求错误
        return Promise.reject(error);
    }
);

//响应拦截器
service.interceptors.response.use(
    (response) => {
        //响应成功
        if (response.config.isLoad) hideLoading();
        if (response.status >= 200 && response.status < 300) {
            const data = response.data || {}
            const retMsg = data.retMsg || data.errMsg;
            const retCode = data.code || '';
            if (retCode == 200) {
                return Promise.resolve(data)
            } else {
                Toast(retMsg)
                return Promise.reject(new Error(retMsg))
            }
        }
    },

    (error) => {
        hideLoading()
        let resp = error.response;
        let msg = '';
        if (error.response) {
            // 根据响应状态码，做不同错误处理
            switch (resp.status) {
                case 400:
                    msg = warnWithLogin(resp.status, '请求错误');
                    break;
                case 401:
                case 403:
                    msg = warnWithLogin(resp.status, '未进行认证或认证过期，无法访问资源系统！');
                    // 这里可以做清空storage并跳转到登录页的操作
                    break;
                case 404:
                    msg = warn(resp.status, '请求资源访问出错');
                    break;
                case 408:
                    msg = warn(resp.status, '请求资源访问超时');
                    break;
                case 500:
                case 501:
                case 502:
                case 503:
                case 504:
                    msg = warnWithLogin(resp.status, ERR_MSG);
                    break;
                default:
                    msg = warnWithLogin(resp.status, `连接出错(${resp.status})!`);
            }
            resp = resp.data;
        } else {
            resp = { code: 'error', message: error.message };
        }
        return Promise.reject(error);
    }
);
export default service;
